package com.xlhl.init.aop;

import com.xlhl.init.common.Validatable;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 参数校验切面
 *
 * @author xlhl
 */
@Aspect
@Component
public class ValidationAspect implements Ordered {

    /**
     * 请求参数校验
     * <p>
     * 会拦截 带有 Controller 注解 或 RestController 标识的类
     * 并且他们内部的函数的参数中含有一个或多个 {@link Validatable} 的请求
     * </p>
     * 会调用他们实现的 {@link Validatable#doValidate()} 方法
     *
     * @param point
     */
    @Before(
            "(within(@org.springframework.stereotype.Controller *) || " +
                    "within(@org.springframework.web.bind.annotation.RestController *))" +
                    "&& execution(* *(.., com.xlhl.init.common.Validatable+, ..))"
    )
    public void validateRequestParams(JoinPoint point) {
        Arrays.stream(point.getArgs())
                .filter(args -> args instanceof Validatable)
                .forEach(args -> ((Validatable) args).validate());
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
